/**********************************************************************************
 * $URL$
 * $Id$
 ***********************************************************************************
 *
 * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008 Sakai Foundation
 *
 * Licensed under the Educational Community License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.opensource.org/licenses/ECL-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 **********************************************************************************/

package org.sakaiproject.content.api;

import java.io.InputStream;
import java.net.URI;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.Stack;
import java.util.TreeSet;

import org.sakaiproject.antivirus.api.VirusFoundException;
import org.sakaiproject.authz.api.AuthzPermissionException;
import org.sakaiproject.entity.api.Entity;
import org.sakaiproject.entity.api.EntityProducer;
import org.sakaiproject.entity.api.ResourceProperties;
import org.sakaiproject.entity.api.ResourcePropertiesEdit;
import org.sakaiproject.exception.IdInvalidException;
import org.sakaiproject.exception.IdLengthException;
import org.sakaiproject.exception.IdUniquenessException;
import org.sakaiproject.exception.IdUnusedException;
import org.sakaiproject.exception.IdUsedException;
import org.sakaiproject.exception.InUseException;
import org.sakaiproject.exception.InconsistentException;
import org.sakaiproject.exception.OverQuotaException;
import org.sakaiproject.exception.PermissionException;
import org.sakaiproject.exception.ServerOverloadException;
import org.sakaiproject.exception.TypeException;
import org.sakaiproject.time.api.Time;
import org.sakaiproject.util.MergeConfig;
import org.w3c.dom.Document;

/**
 * <p>
 * ContentHostingService is the Interface for Sakai Content Hosting services. This service is based on WebDAV for terminology and capability, although it may be implemented using some other content management framework.
 * </p>
 * <p>
 * The ContentHostingService manages shared content resources and collections. A resource is a file of some media type (MIME, such as image/gif, text/html, etc), with a resource id (a URI) and properties (name value pairs), as described in WebDAV.
 * </p>
 * <p>
 * Resources are organized in collections. A collection is a list of resource ids, and is itself a resource with a resource id. In the spirit of WebDAV, a resource must be placed into a collection, and the containing collection must exist before the
 * resource is added.
 * </p>
 * <p>
 * Resource ids used in the API with the service are relative to the root "/" collection of the service. The full URL to a resource can be accessed from the service or from a resource object.
 * </p>
 * <p>
 * Resources have any number of properties. A property is defined by a name, which includes an XML namespace, and a value, which is any string. Some properties are pre-defined (by the DAV: namespace), and are "live"; the value is generated by the service.
 * Other properties are "dead", the values are maintained by the users. Properties from namespaces other than "DAV:" are accepted.
 * </p>
 * <p>
 * TO DO:
 * <ul>
 * <li>add copy, move to collection and resource</li>
 * <li>add lock</li>
 * <li>add version control</li>
 * </ul>
 * </p>
 * <p>
 * The ContentHostingService can be asked:
 * <ul>
 * <li>access, create or delete a collection resource.</li>
 * <li>access, create or delete a non-collection resource in a collection.</li>
 * <li>access, add to or delete properties of a resource.</li>
 * </ul>
 * See the methods in this API for details.
 * </p>
 * <p>
 * Security is enforced and Usage Events are generated when there are these accesses:
 * <ul>
 * <li>create a resource: content.new</li>
 * <li>read a resource: content.read</li>
 * <li>update the contents/properties of a resource: content.revise</li>
 * <li>removing a resource: content.delete</li>
 * </ul>
 * </p>
 */
public interface ContentHostingService extends EntityProducer
{
	/** The type string for this application: should not change over time as it may be stored in various parts of persistent entities. */
	static final String APPLICATION_ID = "sakai:content";

	
	public static final String CONDITIONAL_ACCESS_LIST = "conditional_access_list";

	/** This string starts the references to resources in this service. */
	public static final String REFERENCE_ROOT = Entity.SEPARATOR + "content";

	/** Name of the event when creating a resource. */
	public static final String EVENT_RESOURCE_ADD = "content.new";

	/** Name of the event when reading a resource. */
	public static final String EVENT_RESOURCE_READ = "content.read";
	
	public static final String EVENT_RESOURCE_ZIP_DOWNLOAD = "content.zipdownload";

	/** Name of the event when writing a resource. */
	public static final String EVENT_RESOURCE_WRITE = "content.revise";

	/** Name of the event when removing a resource. */
	public static final String EVENT_RESOURCE_REMOVE = "content.delete";
	
	/** Name of the event when a resource becomes available (e.g. scheduled release date) */
	public static final String EVENT_RESOURCE_AVAILABLE = "content.available";

	/** Name of the event when a resource becomes unavailable (e.g. scheduled retract date) */
	public static final String EVENT_RESOURCE_UNAVAILABLE = "content.unavailable";

	/** 
	 * Name of the event when the availability of a content-entity changes - includes 
	 * transitions between hidden and shown, changes in release/retraction dates,
	 * and changes in ConditionalRelease status. 
	 */
	public static final String EVENT_RESOURCE_UPD_VISIBILITY = "content.upd.visibility";

	/** 
	 * Name of the event when access to a content-entity changes - specifically whenever 
	 * a change is made in the groups that can see a content_resource or content_collection 
	 * or in its public/site/group access settings. 
	 */
	public static final String EVENT_RESOURCE_UPD_ACCESS = "content.upd.access";
	
	/** 
	 * Name of the event when the title (or display name) for a content-resource changes. 
	 */
	public static final String EVENT_RESOURCE_UPD_TITLE = "content.upd.title";

	/** 
	 * Name of the event when the file of a content-resource changes. 
	 */
	public static final String EVENT_RESOURCE_UPD_NEW_VERSION = "content.upd.new.version";

	/** Security function for creating a resource. */
	public static final String AUTH_RESOURCE_ADD = "content.new";

	/** Security function for reading a resource. */
	public static final String AUTH_RESOURCE_READ = "content.read";

	/** Security function for writing any resource. */
	public static final String AUTH_RESOURCE_WRITE_ANY = "content.revise.any";

	/** Security function for writing own resource. */
	public static final String AUTH_RESOURCE_WRITE_OWN = "content.revise.own";

	/** Security function for removing any resource. */
	public static final String AUTH_RESOURCE_REMOVE_ANY = "content.delete.any";
	
	/** Security function for removing own resource. */
	public static final String AUTH_RESOURCE_REMOVE_OWN = "content.delete.own";
	
	/** Security function granted to users who will then have membership in all site groups based on their site membership. */
	public static final String AUTH_RESOURCE_ALL_GROUPS = "content.all.groups";

	/** Security function for accessing a resource belonging to a group. */
	public static final String AUTH_GROUP_RESOURCE_READ = "content.read_group_resources";
	
	/** Security function for those who may OWN a dropbox. */
	public static final String AUTH_DROPBOX_OWN = "dropbox.own";
	
	/** Security function for those who may maintain dropboxes of their groups/sections. */
	public static final String AUTH_DROPBOX_GROUPS = "dropbox.maintain.own.groups";

	/** Security function for those who may maintain dropboxes. */
	public static final String AUTH_DROPBOX_MAINTAIN = "dropbox.maintain";

	/** Security function for those who may modify their own content within dropboxes they maintain. */
	public static final String AUTH_DROPBOX_WRITE_OWN = "dropbox.write.own";

	/** Security function for those who may modify any content within dropboxes they maintain. */
	public static final String AUTH_DROPBOX_WRITE_ANY = "dropbox.write.any";

	/** Security function for those who may remove their own content within dropboxes they maintain. */
	public static final String AUTH_DROPBOX_REMOVE_OWN = "dropbox.delete.own";

	/** Security function for those who may remove any content within dropboxes they maintain. */
	public static final String AUTH_DROPBOX_REMOVE_ANY = "dropbox.delete.any";

	/** Security function for accessing hidden entities */
	public static final String AUTH_RESOURCE_HIDDEN = "content.hidden";
	
	/** Property name on a Resource that will cause getUrl() and getRefernce() to return an alternal root reference. */
	public static final String PROP_ALTERNATE_REFERENCE = "sakai:reference-root";
	
	/** Property name on an Individual Dropbox identifying the time when items in the dropbox were most recently added, removed or modified. */
	public static final String PROP_DROPBOX_CHANGE_TIMESTAMP = "sakai:dropbox_change_timestamp";

	/** The maximum number of characters allowed in a new resource ID: make is so the reference, /content/<id>, is 255 or less */
	public static final int MAXIMUM_RESOURCE_ID_LENGTH = 247;
	
	/** Number of times to attempt to find a unique resource id when copying or moving a resource */
	public static final int MAXIMUM_ATTEMPTS_FOR_UNIQUENESS = 100;
	
	/** The maximum number of resources that can be returned by getResourcesOfType() */
	public static final int MAXIMUM_PAGE_SIZE = 1028;
   
	/** 
	 * When assigning default priority (for "priority" sort) folders come before files, 
	 * so files get "priority" much higher than folders.  Add the offset to folder priorities  
	 * to force all files to sort after folders 
	 */
	public static final int CONTENT_RESOURCE_PRIORITY_OFFSET = Integer.MAX_VALUE / 8;

	/** The collection id for the attachments collection */
    public static final String ATTACHMENTS_COLLECTION = "/attachment/";

	/** Collection id for the user sites. */
    public static final String COLLECTION_USER = "/user/";

	/** Collection id for the non-user sites. */
    public static final String COLLECTION_SITE = "/group/";

	/** The content root collection for dropboxes. */
    public static final String COLLECTION_DROPBOX = "/group-user/";

	/** The content root collection for items that are public. */
    public static final String COLLECTION_PUBLIC = "/public/";

	/** The content root collection for items that are hidden. */
    public static final String COLLECTION_PRIVATE = "/private/";

	/** The content root collection for meleteDocs */
    public static final String COLLECTION_MELETE_DOCS = "/meleteDocs/";

	/** A "list" of all root-level collections */
    public static final Set<String> ROOT_COLLECTIONS = new TreeSet<String>();
    
    /** Enable zip content handling (affects resources) */
    public static final String RESOURCES_ZIP_ENABLE = "content.zip.enabled";

    /** Set the limit of the max number of files to extract from a zip archive */
    public static final String RESOURCES_ZIP_EXPAND_MAX = "content.zip.expand.maxfiles";

    /** Enable zip file expansion into content (affects resources) */
    public static final String RESOURCES_ZIP_ENABLE_EXPAND = "content.zip.expand.enabled";
    
    /** Enable content compression into zip file (affects resources) */
    public static final String RESOURCES_ZIP_ENABLE_COMPRESS = "content.zip.compress.enabled";

	static final String ID_LENGTH_EXCEPTION = "id_length_exception";

	public static final String HTML_MIMETYPE = "text/html";
	public static final String DOC_MIMETYPE = "application/msword";
	public static final String DOCX_MIMETYPE
		= "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
	public static final String ODT_MIMETYPE = "application/vnd.oasis.opendocument.text";
	public static final String ODP_MIMETYPE = "application/vnd.oasis.opendocument.presentation";
	public static final String PDF_MIMETYPE = "application/pdf";
	public static final String PPT_MIMETYPE = "application/vnd.ms-powerpoint";
	public static final String PPTX_MIMETYPE = "application/vnd.openxmlformats-officedocument.presentationml.presentation";

	/** Used as a property key to indicate that a document has a preview copy. The value will be
	 * the preview document's id
	 */
	public static final String PREVIEW = "PREVIEW";

    // These are used by the built in getHtmlForRef converter. NOT the fileconversionservice. Used
    // as a key in the returned content map to indicate the status of the conversiont.
    public static final String CONVERSION_TOO_BIG = "CONVERSION_TOO_BIG";
    public static final String CONVERSION_OK = "CONVERSION_OK";
    public static final String CONVERSION_FAILED = "CONVERSION_FAILED";
    public static final String CONVERSION_NOT_SUPPORTED = "CONVERSION_NOT_SUPPORTED";

	public static final String SAK_PROP_MAX_UPLOAD_FILE_SIZE = "content.upload.max";

	/**
	 * The default names for the direct-upload folders.
	 */
	public static final String DEFAULT_INSTRUCTOR_FOLDER = "instructor-uploads";
	public static final String DEFAULT_STUDENT_FOLDER = "student-uploads";

	/**
	 * Used for hard delete of resources of type citation list
	 */
	public static final String CITATIONS_HARD_DELETE_EVENT = "citations.hard.delete";
	public static final String CITATIONS_RESOURCE_TYPE_ID = "org.sakaiproject.citation.impl.CitationList";

	/**
    * For a given id, return its UUID (creating it if it does not already exist)
    */
   public String getUuid(String id);

   /**
    *
    * @param id id of the resource to set the UUID for
    * @param uuid the new UUID of the resource
    * @throws IdInvalidException if the given resource already has a UUID set
    */
   public void setUuid(String id, String uuid) throws IdInvalidException;

	/**
	 * For a given UUID, attempt to lookup and return the corresponding id (URI)
	 */

	public String resolveUuid(String uuid);

	/**
	 * check permissions for addCollection().
	 * 
	 * @param id
	 *        The channel id.
	 * @return true if the user is allowed to addCollection(id), false if not.
	 */
	public boolean allowAddCollection(String id);

	/**
	 * Create a new collection with the given resource id.
	 * 
	 * @param id
	 *        The id of the collection.
	 * @param properties
	 *        A ResourceProperties object with the properties to add to the new collection.
	 * @exception IdUsedException
	 *            if the id is already in use.
	 * @exception IdInvalidException
	 *            if the id is invalid.
	 * @exception PermissionException
	 *            if the user does not have permission to add a collection, or add a member to a collection.
	 * @exception InconsistentException
	 *            if the containing collection does not exist.
	 * @return a new ContentCollection object.
	 * @deprecated Suggest use of {@link #addCollection(String)} followed by {@link Entity#getProperties()},
	 * 		and {@link #commitCollection(ContentCollectionEdit)}
	 */
	@Deprecated
	public ContentCollection addCollection(String id, ResourceProperties properties) throws IdUsedException, IdInvalidException,
			PermissionException, InconsistentException;

	/**
	 * Create a new collection with the given resource id.
	 * 
	 * @param id
	 *        The id of the collection.
	 * @param properties
	 *        A ResourceProperties object with the properties to add to the new collection.
	 * @param groups
	 *        The (possibly empty) collection (String) of reference-strings for groups to be associated with this entity.
	 * 
	 * @exception IdUsedException
	 *            if the id is already in use.
	 * @exception IdInvalidException
	 *            if the id is invalid.
	 * @exception PermissionException
	 *            if the user does not have permission to add a collection, or add a member to a collection.
	 * @exception InconsistentException
	 *            if the containing collection does not exist.
	 * @return a new ContentCollection object.
	 * @throws InconsistentException 
	 * @throws PermissionException 
	 * @throws IdInvalidException 
	 * @throws IdUsedException 
	 * @deprecated Suggest use of {@link #addCollection(String)} followed by {@link Entity#getProperties()},
	 * 		{@link GroupAwareEdit#setGroupAccess(Collection)} and {@link #commitCollection(ContentCollectionEdit)}
	 */
	@Deprecated
	public ContentCollection addCollection(String id, ResourceProperties properties, Collection<String>  groups) throws IdUsedException, IdInvalidException, PermissionException, InconsistentException;

	/**
	 * Create a new collection with the given resource id.
	 * 
	 * @param id
	 *        The id of the collection.
	 * @param properties
	 *        A ResourceProperties object with the properties to add to the new collection.
	 * @param groups
	 *        The (possibly empty) collection (String) of reference-strings for groups to be associated with this entity.
	 * @param hidden
	 *        A flag indicating that the entity should be hidden from users unless they created the entity or have permission to modify it.
	 * @param releaseDate
	 *        The time at which the entity becomes available to most users. The entity should be available immediately if this value is null.
	 * @param retractDate
	 *        The date after which the entity is no longer available to most users. The entity should be available indefinitely if this value is null.
	 * 
	 * @exception IdUsedException
	 *            if the id is already in use.
	 * @exception IdInvalidException
	 *            if the id is invalid.
	 * @exception PermissionException
	 *            if the user does not have permission to add a collection, or add a member to a collection.
	 * @exception InconsistentException
	 *            if the containing collection does not exist.
	 * @return a new ContentCollection object.
	 * @throws InconsistentException 
	 * @throws PermissionException 
	 * @throws IdInvalidException 
	 * @throws IdUsedException 
	 * @deprecated Suggest use of {@link #addCollection(String)} followed by {@link Entity#getProperties()},
	 * 		{@link GroupAwareEdit#setGroupAccess(Collection)}, {@link GroupAwareEdit#setAvailability(boolean, Instant, Instant)} 
	 * 		and {@link #commitCollection(ContentCollectionEdit)}
	 */
	@Deprecated
	public ContentCollection addCollection(String id, ResourceProperties properties, Collection<String>  groups, boolean hidden, Time releaseDate, Time retractDate) throws IdUsedException, IdInvalidException, PermissionException, InconsistentException;

	/**
	 * Create a new collection with the given resource id, locked for update. Must commitCollection() to make official, or cancelCollection() when done!
	 * 
	 * @param id
	 *        The id of the collection.
	 * @exception IdUsedException
	 *            if the id is already in use.
	 * @exception IdInvalidException
	 *            if the id is invalid.
	 * @exception PermissionException
	 *            if the user does not have permission to add a collection, or add a member to a collection.
	 * @exception InconsistentException
	 *            if the containing collection does not exist.
	 * @return a new ContentCollection object.
	 */
	public ContentCollectionEdit addCollection(String id) throws IdUsedException, IdInvalidException, PermissionException,
			InconsistentException;

	/**
	 * Check permissions for getCollection().
	 * 
	 * @param id
	 *        The id of the collection.
	 * @return true if the user is allowed to getCollection(id), false if not.
	 */
	public boolean allowGetCollection(String id);

	/**
	 * Check access to the collection with this local resource id.
	 * 
	 * @param id
	 *        The id of the collection.
	 * @exception IdUnusedException
	 *            if the id does not exist.
	 * @exception TypeException
	 *            if the resource exists but is not a collection.
	 * @exception PermissionException
	 *            if the user does not have permissions to see this collection (or read through containing collections).
	 */
	public void checkCollection(String id) throws IdUnusedException, TypeException, PermissionException;

	/**
	 * Access the collection with this local resource id. The collection internal members and properties are accessible from the returned Collection object.
	 * 
	 * @param id
	 *        The id of the collection.
	 * @exception IdUnusedException
	 *            if the id does not exist.
	 * @exception TypeException
	 *            if the resource exists but is not a collection.
	 * @exception PermissionException
	 *            if the user does not have permissions to see this collection (or read through containing collections).
	 * @return The ContentCollection object found.
	 */
	public ContentCollection getCollection(String id) throws IdUnusedException, TypeException, PermissionException;

	/**
	 * Count the number of (recursive) children for a given id. examples: With a nested collection structure exactly like this: /a /a/b /a/b/1 /a/b/2 getCollectionSize(/a) returns 3 (due to these three children: /a/b /a/b/1 /a/b/2) getCollectionSize(/a/b)
	 * returns 2 (due to these two children: /a/b/1 /a/b/2) getCollectionSize(/a/b/1) returns 0 (nothing falls below this collection)
	 * 
	 * @param id
	 *        The id of the collection.
	 * @exception IdUnusedException
	 *            if the id does not exist.
	 * @exception TypeException
	 *            if the resource exists but is not a collection.
	 * @exception PermissionException
	 *            if the user does not have permissions to see this collection (or read through containing collections).
	 * @return The number of internal members
	 */
	public int getCollectionSize(String id) throws IdUnusedException, TypeException, PermissionException;

	/**
	 * Access a List of ContentEntities (resources and collections) objects in this path (and below) to which the current user has access.
	 * 
	 * @param id
	 *        A collection id.
	 * @return a List of the ContentEntity objects.
	 */
	public List<ContentEntity> getAllEntities(String id);

	/**
	 * Access a List of all the ContentResource objects in this path (and below) which the current user has access.
	 * 
	 * @param id
	 *        A collection id. This cannot be the root collection.
	 * @return a List of the ContentResource objects.
	 * @throws IllegalArgumentException If the getting all the resources for this collection isn't allowed (eg root).
	 */
	public List<ContentResource> getAllResources(String id);

	/**
	 * Access a List of all the deleted ContentResource objects in this path (and below) which the current user has access.
	 * 
	 * @param id
	 *        A collection id.
	 * @return a List of the ContentResource objects.
	 */
	public List getAllDeletedResources(String id);

	/**
	 * check permissions for editCollection()
	 * 
	 * @param id
	 *        The id of the collection.
	 * @return true if the user is allowed to update the collection, false if not.
	 */
	public boolean allowUpdateCollection(String id);

	/**
	 * Access the collection with this local resource id, locked for update. Must commitCollection() to make official, or cancelCollection() when done! The collection internal members and properties are accessible from the returned Collection object.
	 * 
	 * @param id
	 *        The id of the collection.
	 * @exception IdUnusedException
	 *            if the id does not exist.
	 * @exception TypeException
	 *            if the resource exists but is not a collection.
	 * @exception PermissionException
	 *            if the user does not have permissions to see this collection (or read through containing collections).
	 * @exception InUseException
	 *            if the Collection is locked by someone else.
	 * @return The ContentCollection object found.
	 */
	public ContentCollectionEdit editCollection(String id) throws IdUnusedException, TypeException, PermissionException,
			InUseException;

	/**
	 * check permissions for removeCollection().
	 * 
	 * @param id
	 *        The id of the collection.
	 * @return true if the user is allowed to removeCollection(id), false if not.
	 */
	public boolean allowRemoveCollection(String id);

	/**
	 * Remove a collection and all members of the collection, internal or deeper.
	 * 
	 * @param id
	 *        The id of the collection.
	 * @exception IdUnusedException
	 *            if the id does not exist.
	 * @exception TypeException
	 *            if the resource exists but is not a collection.
	 * @exception PermissionException
	 *            if the user does not have permissions to remove this collection, read through any containing
	 * @exception InUseException
	 *            if the collection or a contained member is locked by someone else. collections, or remove any members of the collection.
	 * @exception ServerOverloadException
	 *            if the server is configured to write the resource body to the filesystem and an attempt to access the resource body of any collection member fails.
	 */
	public void removeCollection(String id) throws IdUnusedException, TypeException, PermissionException, InUseException,
			ServerOverloadException;

	/**
	 * Remove just a collection. It must be empty.
	 * 
	 * @param edit
	 *        The collection to remove.
	 * @exception TypeException
	 *            if the resource exists but is not a collection.
	 * @exception PermissionException
	 *            if the user does not have permissions to remove this collection, read through any containing
	 * @exception InconsistentException
	 *            if the collection has members, so that the removal would leave things in an inconsistent state.
	 * @exception ServerOverloadException
	 *            if the server is configured to write the resource body to the filesystem and an attempt to access the resource body of any collection member fails.
	 */
	public void removeCollection(ContentCollectionEdit edit) throws TypeException, PermissionException, InconsistentException,
			ServerOverloadException;

	/**
	 * Commit the changes made, and release the lock. The Object is disabled, and not to be used after this call.
	 * 
	 * @param edit
	 *        The ContentCollectionEdit object to commit.
	 * @throws PermissionException 
	 */
	public void commitCollection(ContentCollectionEdit edit);

	/**
	 * Cancel the changes made object, and release the lock. The Object is disabled, and not to be used after this call.
	 * 
	 * @param edit
	 *        The ContentCollectionEdit object to commit.
	 */
	public void cancelCollection(ContentCollectionEdit edit);

	/** copy %%%, move * */

	/**
	 * check permissions for addResource().
	 * 
	 * @param id
	 *        The id of the new resource.
	 * @return true if the user is allowed to addResource(id), false if not.
	 */
	public boolean allowAddResource(String id);

	/**
	 * Create a new resource with the given properties.
	 * 
	 * @param id
	 *        The id of the new resource.
	 * @param type
	 *        The mime type string of the resource.
	 * @param content
	 *        An array containing the bytes of the resource's content.
	 * @param properties
	 *        A ResourceProperties object with the properties to add to the new resource.
	 * @param priority
	 *        The notification priority for this commit.
	 * @exception PermissionException
	 *            if the user does not have permission to add a resource to the containing collection.
	 * @exception IdUsedException
	 *            if the resource id is already in use.
	 * @exception IdInvalidException
	 *            if the resource id is invalid.
	 * @exception InconsistentException
	 *            if the containing collection does not exist.
	 * @exception OverQuotaException
	 *            if this would result in being over quota.
	 * @exception ServerOverloadException
	 *            if the server is configured to write the resource body to the filesystem and the save fails.
	 * @return a new ContentResource object.
	 * @deprecated Suggest use of {@link #addResource(String)} followed by {@link Entity#getProperties()},
	 * 		and {@link #commitResource(ContentResourceEdit)}
	 */
	@Deprecated
	public ContentResource addResource(String id, String type, byte[] content, ResourceProperties properties, int priority)
			throws PermissionException, IdUsedException, IdInvalidException, InconsistentException, OverQuotaException,
			ServerOverloadException;

	/**
	 * Create a new resource with the given properties.
	 * 
	 * @param id
	 *        The id of the new resource.
	 * @param type
	 *        The mime type string of the resource.
	 * @param content
	 *        A stream containing the bytes of the resource's content.
	 * @param properties
	 *        A ResourceProperties object with the properties to add to the new resource.
	 * @param priority
	 *        The notification priority for this commit.
	 * @exception PermissionException
	 *            if the user does not have permission to add a resource to the containing collection.
	 * @exception IdUsedException
	 *            if the resource id is already in use.
	 * @exception IdInvalidException
	 *            if the resource id is invalid.
	 * @exception InconsistentException
	 *            if the containing collection does not exist.
	 * @exception OverQuotaException
	 *            if this would result in being over quota.
	 * @exception ServerOverloadException
	 *            if the server is configured to write the resource body to the filesystem and the save fails.
	 * @return a new ContentResource object.
	 */
	public ContentResource addResource(String id, String type, InputStream content, ResourceProperties properties, int priority)
		throws PermissionException, IdUsedException, IdInvalidException, InconsistentException, OverQuotaException,
		ServerOverloadException;
	
	/**
	 * Create a new resource with the given resource name used as a resource id within the
	 * specified collection or (if that id is already in use) with a resource id based on
	 * a variation on the name to achieve a unique id, provided a unique id can be found 
	 * before a limit is reached on the number of attempts to achieve uniqueness.
	 * 
	 * @param name
	 *        The name of the new resource (such as a filename).
	 * @param collectionId
	 *        The id of the collection to which the resource should be added.
	 * @param limit
	 *        The maximum number of attempts at finding a unique id based on the given id.
	 * @param type
	 *        The mime type string of the resource.
	 * @param content
	 *        An array containing the bytes of the resource's content.
	 * @param properties
	 *        A ResourceProperties object with the properties to add to the new resource.
	 * @param priority
	 *        The notification priority for this commit.
	 * @exception PermissionException
	 *            if the user does not have permission to add a resource to the containing collection.
	 * @exception IdUniquenessException
	 *            if a unique resource id cannot be found before the limit on the number of attempts is reached.
	 * @exception IdLengthException
	 *            if the resource id exceeds the maximum number of characters for a valid resource id.
	 * @exception IdInvalidException
	 *            if the resource id is invalid.
	 * @exception InconsistentException
	 *            if the containing collection does not exist.
	 * @exception OverQuotaException
	 *            if this would result in being over quota.
	 * @exception ServerOverloadException
	 *            if the server is configured to write the resource body to the filesystem and the save fails.
	 * @return a new ContentResource object.
	 * @deprecated Suggest use of {@link #addResource(String)} or {@link #addResource(String, String, String, int)}} 
	 * 		followed by {@link Entity#getProperties()} and {@link #commitResource(ContentResourceEdit)}
	 */
	@Deprecated
	public ContentResource addResource(String name, String collectionId, int limit, String type, byte[] content, ResourceProperties properties, int priority)
			throws PermissionException, IdUniquenessException, IdLengthException, IdInvalidException, InconsistentException, IdLengthException, OverQuotaException,
			ServerOverloadException;

	/**
	 * Create a new resource with the given id and attributes, including group awareness.
	 * 
	 * @param id
	 *        The id of the new resource.
	 * @param type
	 *        The mime type string of the resource.
	 * @param content
	 *        An array containing the bytes of the resource's content.
	 * @param properties
	 *        A ResourceProperties object with the properties to add to the new resource.
	 * @param groups
	 *        A collection (String) of references to Group objects representing the site subgroups that should have access to this entity.
	 *        May be empty to indicate access is not limited to a group or groups.
	 * @param priority
	 *        The notification priority for this commit.
	 * @exception PermissionException
	 *            if the user does not have permission to add a resource to the containing collection.
	 * @exception IdUsedException
	 *            if the resource id is already in use.
	 * @exception IdInvalidException
	 *            if the resource id is invalid.
	 * @exception InconsistentException
	 *            if the containing collection does not exist.
	 * @exception OverQuotaException
	 *            if this would result in being over quota.
	 * @exception ServerOverloadException
	 *            if the server is configured to write the resource body to the filesystem and the save fails.
	 * @return a new ContentResource object.
	 * @deprecated Suggest use of {@link #addResource(String)} or {@link #addResource(String, String, String, int)}} 
	 * 		followed by {@link Entity#getProperties()} and {@link #commitResource(ContentResourceEdit)}
	 */
	@Deprecated
	public ContentResource addResource(String id, String type, byte[] content, ResourceProperties properties, Collection<String>  groups, int priority)
			throws PermissionException, IdUsedException, IdInvalidException, InconsistentException, OverQuotaException,
			ServerOverloadException;

	/**
	 * Create a new resource with the given id and attributes, including group awareness.
	 * 
	 * @param id
	 *        The id of the new resource.
	 * @param type
	 *        The mime type string of the resource.
	 * @param content
	 *        A stream containing the bytes of the resource's content.
	 * @param properties
	 *        A ResourceProperties object with the properties to add to the new resource.
	 * @param groups
	 *        A collection (String) of references to Group objects representing the site subgroups that should have access to this entity.
	 *        May be empty to indicate access is not limited to a group or groups.
	 * @param priority
	 *        The notification priority for this commit.
	 * @exception PermissionException
	 *            if the user does not have permission to add a resource to the containing collection.
	 * @exception IdUsedException
	 *            if the resource id is already in use.
	 * @exception IdInvalidException
	 *            if the resource id is invalid.
	 * @exception InconsistentException
	 *            if the containing collection does not exist.
	 * @exception OverQuotaException
	 *            if this would result in being over quota.
	 * @exception ServerOverloadException
	 *            if the server is configured to write the resource body to the filesystem and the save fails.
	 * @return a new ContentResource object.
	 */
	public ContentResource addResource(String id, String type, InputStream content, ResourceProperties properties, Collection groups, int priority)
		throws PermissionException, IdUsedException, IdInvalidException, InconsistentException, OverQuotaException,
		ServerOverloadException;
	
	/**
	 * Create a new resource with the given resource name used as a resource id within the
	 * specified collection or (if that id is already in use) with a resource id based on
	 * a variation on the name to achieve a unique id, provided a unique id can be found 
	 * before a limit is reached on the number of attempts to achieve uniqueness.
	 * 
	 * @param name
	 *        The name of the new resource (such as a filename).
	 * @param collectionId
	 *        The id of the collection to which the resource should be added.
	 * @param limit
	 *        The maximum number of attempts at finding a unique id based on the given id.
	 * @param type
	 *        The mime type string of the resource.
	 * @param content
	 *        An array containing the bytes of the resource's content.
	 * @param properties
	 *        A ResourceProperties object with the properties to add to the new resource.
	 * @param groups
	 *        A collection (String) of references to Group objects representing the site subgroups that should have access to this entity.
	 *        May be empty to indicate access is not limited to a group or groups.
	 * @param priority
	 *        The notification priority for this commit.
	 * @exception PermissionException
	 *            if the user does not have permission to add a resource to the containing collection.
	 * @exception IdUniquenessException
	 *            if a unique resource id cannot be found before the limit on the number of attempts is reached.
	 * @exception IdLengthException
	 *            if the resource id exceeds the maximum number of characters for a valid resource id.
	 * @exception IdInvalidException
	 *            if the resource id is invalid.
	 * @exception InconsistentException
	 *            if the containing collection does not exist.
	 * @exception OverQuotaException
	 *            if this would result in being over quota.
	 * @exception ServerOverloadException
	 *            if the server is configured to write the resource body to the filesystem and the save fails.
	 * @return a new ContentResource object.
	 * @deprecated Suggest use of {@link #addResource(String)} or {@link #addResource(String, String, String, int)}} 
	 * 		followed by {@link Entity#getProperties()} and {@link #commitResource(ContentResourceEdit)}
	 */
	@Deprecated
	public ContentResource addResource(String name, String collectionId, int limit, String type, byte[] content, ResourceProperties properties, Collection<String>  groups, int priority)
			throws PermissionException, IdUniquenessException, IdLengthException, IdInvalidException, InconsistentException, IdLengthException, OverQuotaException,
			ServerOverloadException;

	/**
	 * Create a new resource with the given resource name used as a resource id within the
	 * specified collection or (if that id is already in use) with a resource id based on
	 * a variation on the name to achieve a unique id, provided a unique id can be found 
	 * before a limit is reached on the number of attempts to achieve uniqueness.
	 * 
	 * @param name
	 *        The name of the new resource (such as a filename).
	 * @param collectionId
	 *        The id of the collection to which the resource should be added.
	 * @param limit
	 *        The maximum number of attempts at finding a unique id based on the given id.
	 * @param type
	 *        The mime type string of the resource.
	 * @param content
	 *        An array containing the bytes of the resource's content.
	 * @param properties
	 *        A ResourceProperties object with the properties to add to the new resource.
	 * @param groups
	 *        A collection (String) of references to Group objects representing the site subgroups that should have access to this entity.
	 *        May be empty to indicate access is not limited to a group or groups.
	 * @param hidden
	 *        A flag indicating that the entity should be hidden from users unless they created the entity or have permission to modify it.
	 * @param releaseDate
	 *        The time at which the entity becomes available to most users. The entity should be available immediately if this value is null.
	 * @param retractDate
	 *        The date after which the entity is no longer available to most users. The entity should be available indefinitely if this value is null.
	 * @param priority
	 *        The notification priority for this commit.
	 * @exception PermissionException
	 *            if the user does not have permission to add a resource to the containing collection.
	 * @exception IdUniquenessException
	 *            if a unique resource id cannot be found before the limit on the number of attempts is reached.
	 * @exception IdLengthException
	 *            if the resource id exceeds the maximum number of characters for a valid resource id.
	 * @exception IdInvalidException
	 *            if the resource id is invalid.
	 * @exception InconsistentException
	 *            if the containing collection does not exist.
	 * @exception OverQuotaException
	 *            if this would result in being over quota.
	 * @exception ServerOverloadException
	 *            if the server is configured to write the resource body to the filesystem and the save fails.
	 * @return a new ContentResource object.
	 * @deprecated Suggest use of {@link #addResource(String)} or {@link #addResource(String, String, String, int)}} 
	 * 		followed by {@link Entity#getProperties()} and {@link #commitResource(ContentResourceEdit)}
	 */
	@Deprecated
	public ContentResource addResource(String name, String collectionId, int limit, String type, byte[] content, ResourceProperties properties, Collection<String>  groups, boolean hidden, Time releaseDate, Time retractDate, int priority)
			throws PermissionException, IdUniquenessException, IdLengthException, IdInvalidException, InconsistentException, IdLengthException, OverQuotaException,
			ServerOverloadException;

	/**
	 * Create a new resource with the given resource name used as a resource id within the
	 * specified collection or (if that id is already in use) with a resource id based on
	 * a variation on the name to achieve a unique id, provided a unique id can be found 
	 * before a limit is reached on the number of attempts to achieve uniqueness.
	 * 
	 * @param name
	 *        The name of the new resource (such as a filename).
	 * @param collectionId
	 *        The id of the collection to which the resource should be added.
	 * @param limit
	 *        The maximum number of attempts at finding a unique id based on the given id.
	 * @param type
	 *        The mime type string of the resource.
	 * @param content
	 *        An array containing the bytes of the resource's content.
	 * @param properties
	 *        A ResourceProperties object with the properties to add to the new resource.
	 * @param groups
	 *        A collection (String) of references to Group objects representing the site subgroups that should have access to this entity.
	 *        May be empty to indicate access is not limited to a group or groups.
	 * @param hidden
	 *        A flag indicating that the entity should be hidden from users unless they created the entity or have permission to modify it.
	 * @param releaseDate
	 *        The time at which the entity becomes available to most users. The entity should be available immediately if this value is null.
	 * @param retractDate
	 *        The date after which the entity is no longer available to most users. The entity should be available indefinitely if this value is null.
	 * @param priority
	 *        The notification priority for this commit.
	 * @exception PermissionException
	 *            if the user does not have permission to add a resource to the containing collection.
	 * @exception IdUniquenessException
	 *            if a unique resource id cannot be found before the limit on the number of attempts is reached.
	 * @exception IdLengthException
	 *            if the resource id exceeds the maximum number of characters for a valid resource id.
	 * @exception IdInvalidException
	 *            if the resource id is invalid.
	 * @exception InconsistentException
	 *            if the containing collection does not exist.
	 * @exception OverQuotaException
	 *            if this would result in being over quota.
	 * @exception ServerOverloadException
	 *            if the server is configured to write the resource body to the filesystem and the save fails.
	 * @return a new ContentResource object.
	 */
	public ContentResource addResource(String name, String collectionId, int limit, String type, InputStream content, ResourceProperties properties, Collection groups, boolean hidden, Time releaseDate, Time retractDate, int priority)
			throws PermissionException, IdUniquenessException, IdLengthException, IdInvalidException, InconsistentException, IdLengthException, OverQuotaException,
			ServerOverloadException;
	
	/**
	 * Create a new resource with the given resource id, locked for update. Must commitResource() to make official, or cancelResource() when done!
	 * 
	 * @param id
	 *        The id of the new resource.
	 * @exception PermissionException
	 *            if the user does not have permission to add a resource to the containing collection.
	 * @exception IdUsedException
	 *            if the resource id is already in use.
	 * @exception IdInvalidException
	 *            if the resource id is invalid.
	 * @exception InconsistentException
	 *            if the containing collection does not exist.
	 * @exception ServerOverloadException
	 *            if the server is configured to write the resource body to the filesystem and the save fails.
	 * @return a new ContentResource object.
	 */
	public ContentResourceEdit addResource(String id) throws PermissionException, IdUsedException, IdInvalidException,
			InconsistentException, ServerOverloadException;

	/**
	 * check permissions for addAttachmentResource().
	 * 
	 * @return true if the user is allowed to addAttachmentResource(), false if not.
	 */
	public boolean allowAddAttachmentResource();
	
	/**
	 * Check whether a resource id or collection id references an entity in the attachments collection. 
	 * This method makes no guarantees that a resource actually exists with this id.
	 * @param id	Assumed to be a valid resource id or collection id.
	 * @return	true if the id (assuming it is a valid id for an existing resource or collection) 
	 * references an entity in the hidden attachments area created through one of this class's 
	 * addAttachmentResource methods. 
	 */
	public boolean isAttachmentResource(String id);

	/**
	 * Create a new resource as an attachment to some other resource in the system. The new resource will be placed 
	 * into a newly created collecion in the attachment collection, with an auto-generated id, and given the specified 
	 * resource name within this collection.
	 * 
	 * @param name
	 *        The name of the new resource, i.e. a partial id relative to the collection where it will live.
	 * @param type
	 *        The mime type string of the resource.
	 * @param content
	 *        A stream containing the bytes of the resource's content.
	 * @param properties
	 *        A ResourceProperties object with the properties to add to the new resource.
	 * @exception IdUsedException
	 *            if the resource name is already in use (not likely, as the containing collection is auto-generated!)
	 * @exception IdInvalidException
	 *            if the resource name is invalid.
	 * @exception InconsistentException
	 *            if the containing collection (or it's containing collection...) does not exist.
	 * @exception PermissionException
	 *            if the user does not have permission to add a collection, or add a member to a collection.
	 * @exception OverQuotaException
	 *            if this would result in being over quota.
	 * @exception ServerOverloadException
	 *            if the server is configured to write the resource body to the filesystem and the save fails.
	 * @return a new ContentResource object.
	 * @deprecated Suggest use of {@link #addAttachmentResource(String, String, String, String, InputStream, ResourceProperties)}
	 */
	@Deprecated
	public ContentResource addAttachmentResource(String name, String type, byte[] content, ResourceProperties properties)
		throws IdInvalidException, InconsistentException, IdUsedException, PermissionException, OverQuotaException,
		ServerOverloadException;
	
	/**
	 * Create a new resource as an attachment to some other resource in the system. The new resource will be placed 
	 * into a newly created collecion in the attachment collection, with an auto-generated id, and given the specified 
	 * resource name within this collection.
	 * 
	 * @param name
	 *        The name of the new resource, i.e. a partial id relative to the collection where it will live.
	 * @param type
	 *        The mime type string of the resource.
	 * @param content
	 *        A stream containing the bytes of the resource's content.
	 * @param properties
	 *        A ResourceProperties object with the properties to add to the new resource.
	 * @exception IdUsedException
	 *            if the resource name is already in use (not likely, as the containing collection is auto-generated!)
	 * @exception IdInvalidException
	 *            if the resource name is invalid.
	 * @exception InconsistentException
	 *            if the containing collection (or it's containing collection...) does not exist.
	 * @exception PermissionException
	 *            if the user does not have permission to add a collection, or add a member to a collection.
	 * @exception OverQuotaException
	 *            if this would result in being over quota.
	 * @exception ServerOverloadException
	 *            if the server is configured to write the resource body to the filesystem and the save fails.
	 * @return a new ContentResource object.
	 */
	public ContentResource addAttachmentResource(String name, String type, InputStream content, ResourceProperties properties)
			throws IdInvalidException, InconsistentException, IdUsedException, PermissionException, OverQuotaException,
			ServerOverloadException;

	/**
	 * Create a new resource as an attachment to some other resource in the system. The new resource will be placed 
	 * into a newly created collection in the site collection within the attachment collection. The new collection 
	 * will have an auto-generated id, and it will be given the specified resource name within the site collection.
	 * 
	 * @param name
	 *        The name of the new resource, i.e. a partial id relative to the collection where it will live.
	 * @param site
	 *        The string identifier for the site where the attachment is being added within the attachments collection.
	 * @param tool
	 *        The display-name for the tool through which the attachment is being added within the site's attachments collection.
	 * @param type
	 *        The mime type string of the resource.
	 * @param content
	 *        An array containing the bytes of the resource's content.
	 * @param properties
	 *        A ResourceProperties object with the properties to add to the new resource.
	 * @exception IdUsedException
	 *            if the resource name is already in use (not likely, as the containing collection is auto-generated!)
	 * @exception IdInvalidException
	 *            if the resource name is invalid.
	 * @exception InconsistentException
	 *            if the containing collection (or it's containing collection...) does not exist.
	 * @exception PermissionException
	 *            if the user does not have permission to add a collection, or add a member to a collection.
	 * @exception OverQuotaException
	 *            if this would result in being over quota.
	 * @exception ServerOverloadException
	 *            if the server is configured to write the resource body to the filesystem and the save fails.
	 * @return a new ContentResource object.
	 * @deprecated Suggest use of {@link #addAttachmentResource(String, String, InputStream, ResourceProperties)}
	 */
	@Deprecated
	public ContentResource addAttachmentResource(String name, String site, String tool, String type, byte[] content,
			ResourceProperties properties) throws IdInvalidException, InconsistentException, IdUsedException, PermissionException,
			OverQuotaException, ServerOverloadException;
	
	/**
	 * Create a new resource as an attachment to some other resource in the system. The new resource will be placed 
	 * into a newly created collection in the site collection within the attachment collection. The new collection 
	 * will have an auto-generated id, and it will be given the specified resource name within the site collection.
	 * 
	 * @param name
	 *        The name of the new resource, i.e. a partial id relative to the collection where it will live.
	 * @param site
	 *        The string identifier for the site where the attachment is being added within the attachments collection.
	 * @param tool
	 *        The display-name for the tool through which the attachment is being added within the site's attachments collection.
	 * @param type
	 *        The mime type string of the resource.
	 * @param content
	 *        A stream containing the bytes of the resource's content.
	 * @param properties
	 *        A ResourceProperties object with the properties to add to the new resource.
	 * @exception IdUsedException
	 *            if the resource name is already in use (not likely, as the containing collection is auto-generated!)
	 * @exception IdInvalidException
	 *            if the resource name is invalid.
	 * @exception InconsistentException
	 *            if the containing collection (or it's containing collection...) does not exist.
	 * @exception PermissionException
	 *            if the user does not have permission to add a collection, or add a member to a collection.
	 * @exception OverQuotaException
	 *            if this would result in being over quota.
	 * @exception ServerOverloadException
	 *            if the server is configured to write the resource body to the filesystem and the save fails.
	 * @return a new ContentResource object.
	 */
	public ContentResource addAttachmentResource(String name, String site, String tool, String type, InputStream content,
			ResourceProperties properties) throws IdInvalidException, InconsistentException, IdUsedException, PermissionException,
			OverQuotaException, ServerOverloadException;

	/**
	 * Create a new resource as an attachment to some other resource in the system, locked for update. Must commitResource() 
	 * to make official, or cancelResource() when done! The new resource will be placed into a newly created collecion in the 
	 * attachment collection, with an auto-generated id, and given the specified resource name within this collection.
	 * 
	 * @param name
	 *        The name of the new resource, i.e. a partial id relative to the collection where it will live.
	 * @exception IdUsedException
	 *            if the resource name is already in use (not likely, as the containing collection is auto-generated!)
	 * @exception IdInvalidException
	 *            if the resource name is invalid.
	 * @exception InconsistentException
	 *            if the containing collection (or it's containing collection...) does not exist.
	 * @exception PermissionException
	 *            if the user does not have permission to add a collection, or add a member to a collection.
	 * @exception ServerOverloadException
	 *            if the server is configured to write the resource body to the filesystem and the save fails.
	 * @return a new ContentResource object.
	 */
	public ContentResourceEdit addAttachmentResource(String name) throws IdInvalidException, InconsistentException,
			IdUsedException, PermissionException, ServerOverloadException;

	/**
	 * Copy an attachment from one context to another.
	 *
	 * @param oAttachmentId
	 *      The id of the original attachment. It is a content path to an existing attachment that is readable by the current user
	 *      /attachment/60d0b410-0930-4e73-9f0c-f0effe58b2c8/Discussions/33bdba7a-e8c7-4a17-bcee-0003f0b1a7ee/coursera-visit.jpg
	 * @param toContext
	 *      The site of the new attachment - required
	 * @param toolTitle
	 *      The title of the tool that the attachment is being added to (i.d. Discussions or Assignments) - this will be 
	 *      used to generate the new attachment id / path - required
	 * @param mcx
	 *      The MergeConfig for this import
     *      attachment.  If the oAttachmentId points to a non-existant or inaccessible resource, the attachmentNames map will 
	 *      consulted to see id the oAttachmentId has been pre-imported.
	 * @return The id of the new attachment.
	 */
	public ContentResource copyAttachment(String oAttachmentId, String toContext, String toolTitle, MergeConfig mcx) 
		throws IdUnusedException, TypeException, PermissionException;

	/**
	 * check permissions for updateResource().
	 * 
	 * @param id
	 *        The id of the new resource.
	 * @return true if the user is allowed to updateResource(id), false if not.
	 */
	public boolean allowUpdateResource(String id);

	/**
	 * Update the body and or content type of an existing resource with the given resource id.
	 * 
	 * @param id
	 *        The id of the resource.
	 * @param type
	 *        The mime type string of the resource (if null, no change).
	 * @param content
	 *        An array containing the bytes of the resource's content (if null, no change).
	 * @exception PermissionException
	 *            if the user does not have permission to add a resource to the containing collection or write the resource.
	 * @exception IdUnusedException
	 *            if the resource id is not defined.
	 * @exception TypeException
	 *            if the resource is a collection.
	 * @exception InUseException
	 *            if the resource is locked by someone else.
	 * @exception OverQuotaException
	 *            if this would result in being over quota.
	 * @exception ServerOverloadException
	 *            if the server is configured to write the resource body to the filesystem and the save fails.
	 * @return a new ContentResource object.
	 */
	public ContentResource updateResource(String id, String type, byte[] content) throws PermissionException, IdUnusedException,
			TypeException, InUseException, OverQuotaException, ServerOverloadException;

	/**
	 * Access the resource with this resource id, locked for update. For non-collection resources only. Must commitEdit() to make official, or cancelEdit() when done! The resource content and properties are accessible from the returned Resource object.
	 * 
	 * @param id
	 *        The id of the resource.
	 * @exception PermissionException
	 *            if the user does not have permissions to read the resource or read through any containing collection.
	 * @exception IdUnusedException
	 *            if the resource id is not found.
	 * @exception TypeException
	 *            if the resource is a collection.
	 * @exception InUseException
	 *            if the resource is locked by someone else.
	 * @return the ContentResource object found.
	 */
	public ContentResourceEdit editResource(String id) throws PermissionException, IdUnusedException, TypeException, InUseException;

	/**
	 * check permissions for getResource().
	 * 
	 * @param id
	 *        The id of the new resource.
	 * @return true if the user is allowed to getResource(id), false if not.
	 */
	public boolean allowGetResource(String id);

	/**
	 * Check access to the resource with this local resource id. For non-collection resources only.
	 * 
	 * @param id
	 *        The id of the resource.
	 * @exception PermissionException
	 *            if the user does not have permissions to read the resource or read through any containing collection.
	 * @exception IdUnusedException
	 *            if the resource id is not found.
	 * @exception TypeException
	 *            if the resource is a collection.
	 */
	public void checkResource(String id) throws PermissionException, IdUnusedException, TypeException;

	/**
	 * Access the resource with this resource id. For non-collection resources only. The resource content and properties are accessible from the returned Resource object.
	 * 
	 * @param id
	 *        The id of the resource.
	 * @exception PermissionException
	 *            if the user does not have permissions to read the resource or read through any containing collection.
	 * @exception IdUnusedException
	 *            if the resource id is not found.
	 * @exception TypeException
	 *            if the resource is a collection.
	 * @return the ContentResource object found.
	 */
	public ContentResource getResource(String id) throws PermissionException, IdUnusedException, TypeException;

	/**
	 * check permissions for removeResource().
	 * 
	 * @param id
	 *        The id of the new resource.
	 * @return true if the user is allowed to removeResource(id), false if not.
	 */
	public boolean allowRemoveResource(String id);

	/**
	 * Remove a resource. For non-collection resources only.
	 * 
	 * @param id
	 *        The id of the resource.
	 * @exception PermissionException
	 *            if the user does not have permissions to read a containing collection, or to remove this resource.
	 * @exception IdUnusedException
	 *            if the resource id is not found.
	 * @exception TypeException
	 *            if the resource is a collection.
	 * @exception InUseException
	 *            if the resource is locked by someone else.
	 * @throws ServerOverloadException 
	 */
	public void removeResource(String id) throws PermissionException, IdUnusedException, TypeException, InUseException;

	/**
	 * Remove a resource that is locked for update.
	 * 
	 * @param edit
	 *        The ContentResourceEdit object to remove.
	 * @exception PermissionException
	 *            if the user does not have permissions to read a containing collection, or to remove this resource.
	 * @throws ServerOverloadException 
	 */
	public void removeResource(ContentResourceEdit edit) throws PermissionException;

	/**
	 * check permissions for rename().
	 * 
	 * @param id
	 *        The id of the existing resource.
	 * @return true if the user is allowed to rename(id), false if not.
	 */
	public boolean allowRename(String id, String new_id);

	/**
	 * check permissions for copy().
	 * 
	 * @param id
	 *        The id of the new resource.
	 * @param new_id
	 *        The desired id of the new resource.
	 * @return true if the user is allowed to copy(id,new_id), false if not.
	 */
	public boolean allowCopy(String id, String new_id);

	/**
	 * Copy a resource.
	 * 
	 * @param id
	 *        The id of the resource.
	 * @param new_id
	 *        The desired id of the new resource.
	 * @return The full id of the new copy of the resource.
	 * @exception PermissionException
	 *            if the user does not have permissions to read a containing collection, or to remove this resource.
	 * @exception IdUnusedException
	 *            if the resource id is not found.
	 * @exception TypeException
	 *            if the resource is a collection.
	 * @exception InUseException
	 *            if the resource is locked by someone else.
	 * @exception IdUsedException
	 *            if copied item is a collection and the new id is already in use or if the copied item is not a collection and a unique id cannot be found in some arbitrary number of attempts (@see MAXIMUM_ATTEMPTS_FOR_UNIQUENESS).
	 * @exception ServerOverloadException
	 *            if the server is configured to write the resource body to the filesystem and the save fails.
	 */
	public String copy(String id, String new_id) throws PermissionException, IdUnusedException, TypeException, InUseException,
			OverQuotaException, IdUsedException, ServerOverloadException;

	/**
	 * Copy a collection or resource from one location to another. Creates a new collection with an id similar to new_folder_id and recursively copies all nested collections and resources within thisCollection to the new collection.
	 * 
	 * @param id
	 *        The id of the resource.
	 * @param folder_id
	 *        The id of the folder in which the copy should be created.
	 * @return The full id of the new copy of the resource.
	 * @exception PermissionException
	 *            if the user does not have permissions to read a containing collection, or to remove this resource.
	 * @exception IdUnusedException
	 *            if the resource id is not found.
	 * @exception TypeException
	 *            if the resource is a collection.
	 * @exception InUseException
	 *            if the resource is locked by someone else.
	 * @exception IdLengthException
	 *            if the new id of the copied item (or any nested item) is longer than the maximum length of an id.
	 * @exception IdUniquenessException
	 *            if a unique id cannot be found in the new folder.
	 * @exception InconsistentException
	 *            if the destination folder (folder_id) is contained within the source folder (id).
	 * @exception IdUsedException
	 *            if a unique resource id cannot be found after some arbitrary number of attempts (@see MAXIMUM_ATTEMPTS_FOR_UNIQUENESS).
	 * @exception ServerOverloadException
	 *            if the server is configured to write the resource body to the filesystem and the save fails.
	 */
	public String copyIntoFolder(String id, String folder_id) throws PermissionException, IdUnusedException, TypeException,
			InUseException, OverQuotaException, IdUsedException, ServerOverloadException, InconsistentException, IdLengthException, IdUniquenessException;

	/**
	 * Move a resource or collection to a (different) folder. This may be accomplished by renaming the resource or by recursively renaming the collection and all enclosed members (no matter how deep) to effectively change their locations. Alternatively,
	 * it may be accomplished by copying the resource and recursively copying collections from their existing collection to the new collection and ultimately deleting the original resource(s) and/or collections(s).
	 * 
	 * @param id
	 *        The id of the resource or collection to be moved.
	 * @param folder_id
	 *        The id of the folder to which the resource should be moved.
	 * @return The full id of the resource after the move is completed.
	 * @exception PermissionException
	 *            if the user does not have permissions to read a containing collection, or to remove this resource.
	 * @exception IdUnusedException
	 *            if the resource id is not found.
	 * @exception TypeException
	 *            if the resource is a collection.
	 * @exception InUseException
	 *            if the resource is locked by someone else.
	 * @exception InconsistentException
	 *            if the containing collection does not exist.
	 * @exception InconsistentException
	 *            if the destination folder (folder_id) is contained within the source folder (id).
	 * @exception IdUsedException
	 *            if a unique resource id cannot be found after some arbitrary number of attempts (@see MAXIMUM_ATTEMPTS_FOR_UNIQUENESS).
	 * @exception ServerOverloadException
	 *            if the server is configured to write the resource body to the filesystem and the save fails.
	 */
	public String moveIntoFolder(String id, String folder_id) throws PermissionException, IdUnusedException, TypeException,
			InUseException, OverQuotaException, IdUsedException, InconsistentException, ServerOverloadException;

	/**
	 * Commit the changes made, and release the lock. The Object is disabled, and not to be used after this call.
	 * 
	 * @param edit
	 *        The ContentResourceEdit object to commit.
	 * @exception OverQuotaException
	 *            if this would result in being over quota (the edit is then cancled).
	 * @exception ServerOverloadException
	 *            if the server is configured to write the resource body to the filesystem and the save fails.
	 */
	public void commitResource(ContentResourceEdit edit) throws OverQuotaException, ServerOverloadException, VirusFoundException;

	/**
	 * Commit the changes made, and release the lock. The Object is disabled, and not to be used after this call.
	 * 
	 * @param edit
	 *        The ContentResourceEdit object to commit.
	 * @param priority
	 *        The notification priority of this commit.
	 * @exception OverQuotaException
	 *            if this would result in being over quota (the edit is then cancled).
	 * @exception ServerOverloadException
	 *            if the server is configured to write the resource body to the filesystem and the save fails.
	 */
	public void commitResource(ContentResourceEdit edit, int priority) throws OverQuotaException, ServerOverloadException, VirusFoundException;

	/**
	 * Cancel the changes made object, and release the lock. The Object is disabled, and not to be used after this call.
	 * 
	 * @param edit
	 *        The ContentResourceEdit object to commit.
	 */
	public void cancelResource(ContentResourceEdit edit);

	/** %%% copy, move * */

	/**
	 * check permissions for getProperties().
	 * 
	 * @param id
	 *        The id of the new resource.
	 * @return true if the user is allowed to getProperties(id), false if not.
	 */
	public boolean allowGetProperties(String id);

	/**
	 * Access the properties of a resource with this resource id, either collection or resource.
	 * 
	 * @param id
	 *        The id of the resource.
	 * @exception PermissionException
	 *            if the user does not have permissions to read properties on this object or read through containing collections.
	 * @exception IdUnusedException
	 *            if the resource id is not found.
	 * @return the ResourceProperties object for this resource.
	 */
	public ResourceProperties getProperties(String id) throws PermissionException, IdUnusedException;

	/**
	 * check permissions for addProperty().
	 * 
	 * @param id
	 *        The id of the new resource.
	 * @return true if the user is allowed to addProperty(id), false if not.
	 */
	public boolean allowAddProperty(String id);

	/**
	 * Add / update a property for a collection or resource.
	 * 
	 * @param id
	 *        The id of the resource.
	 * @param name
	 *        The properties name to add or update
	 * @param value
	 *        The new value for the property.
	 * @exception PermissionException
	 *            if the user does not have premissions to write properties on this object or read through containing collections.
	 * @exception IdUnusedException
	 *            if the resource id is not found.
	 * @exception TypeException
	 *            if any property requested cannot be set (it may be live).
	 * @exception InUseException
	 *            if the resource is locked by someone else.
	 * @exception ServerOverloadException
	 *            if the server is configured to write the resource body to the filesystem and the save fails.
	 * @return the ResourceProperties object for this resource.
	 */
	public ResourceProperties addProperty(String id, String name, String value) throws PermissionException, IdUnusedException,
			TypeException, InUseException, ServerOverloadException;

	/**
	 * check permissions for removeProperty().
	 * 
	 * @param id
	 *        The id of the new resource.
	 * @return true if the user is allowed to removeProperty(id), false if not.
	 */
	public boolean allowRemoveProperty(String id);

	/**
	 * Remove a property from a collection or resource.
	 * 
	 * @param id
	 *        The id of the resource.
	 * @param name
	 *        The property name to be removed from the resource.
	 * @exception PermissionException
	 *            if the user does not have premissions to write properties on this object or read through containing collections.
	 * @exception IdUnusedException
	 *            if the resource id is not found.
	 * @exception TypeException
	 *            if the property named cannot be removed.
	 * @exception InUseException
	 *            if the resource is locked by someone else.
	 * @exception ServerOverloadException
	 *            if the server is configured to write the resource body to the filesystem and the save fails.
	 * @return the ResourceProperties object for this resource.
	 */
	public ResourceProperties removeProperty(String id, String name) throws PermissionException, IdUnusedException, TypeException,
			InUseException, ServerOverloadException;

	/**
	 * Access an iterator (Strings) on the names of all properties used in the hosted resources and collections.
	 * 
	 * @return An iterator (Strings) on the names of all properties used in the hosted resources and collections (may be empty).
	 */
	// %%%public Iterator getPropertyNames();

	/**
	 * Access the resource URL from a resource id.
	 * 
	 * @param id
	 *        The resource id.
	 * @return The resource URL.
	 */
	public String getUrl(String id);

	/**
	 * Access the alternate URL which can be used to access the entity.
	 * 
	 * @param id
	 *        The resource id.
	 * @param rootProperty
	 * 		 The name of the entity property whose value controls which alternate reference URL is requested. If null, the native 'raw' URL is requested. 
	 * @return The resource URL.
	 */
	public String getUrl(String id, String rootProperty);

	/**
	 * Access the internal reference from a resource id.
	 * 
	 * @param id
	 *        The resource id.
	 * @return The internal reference from a resource id.
	 */
	public String getReference(String id);

	/**
	 * Access the resource id of the collection which contains this collection or resource.
	 * 
	 * @param id
	 *        The resource id (reference, or URL) of the ContentCollection or ContentResource
	 * @return the resource id (reference, or URL, depending on the id parameter) of the collection which contains this resource.
	 */
	public String getContainingCollectionId(String id);

	/**
	 * Get the depth of the resource/collection object in the hireachy based on the given collection id
	 * 
	 * @param resourceId
	 *        The Id of the resource/collection object to be tested
	 * @param baseCollectionId
	 *        The Id of the collection as the relative root level
	 * @return the integer value reflecting the relative hierarchy depth of the test resource/collection object based on the given base collection level
	 */
	public int getDepth(String resourceId, String baseCollectionId);

	/**
	 * Test if this id (reference, or URL) refers to the root collection.
	 * 
	 * @param id
	 *        The resource id (reference, or URL) of a ContentCollection
	 * @return true if this is the root collection
	 */
	public boolean isRootCollection(String id);

	/**
	 * Construct a stand-alone, not associated with any particular resource, ResourceProperties object.
	 * 
	 * @return The new ResourceProperties object.
	 */
	public ResourcePropertiesEdit newResourceProperties();

	/**
	 * Return the collection id of the root collection for this site id.
	 * 
	 * @param siteId
	 *        The site id.
	 * @return The collection id which is the root collection for this site.
	 */
	String getSiteCollection(String siteId);

	/**
	 * Archive the specified list of resources.
	 * 
	 * @param resources
	 *        A list of the resources to archive.
	 * @param doc
	 *        The document to contain the xml.
	 * @param stack
	 *        The stack of elements, the top of which will be the containing element of the "service.name" element.
	 * @param archivePath
	 *        The path to the folder where we are writing auxilary files.
	 * @return A log of status messages from the archive.
	 */
	String archiveResources(List resources, Document doc, Stack stack, String archivePath);

	/**
	 * Gets all locks set on the resource with this local resource id.
	 * 
	 * @param id
	 * @return
	 */
	Collection getLocks(String id);

	/**
	 * Locks an object (resource or collection) with specified local resource id. Initially, the WebDAV concepts of expiration, exclusive vs shared, and inheritable are not supported; instead, all locks are exclusive. Programmatically created locks may be
	 * designated as "system" locks, in which case, users may not remove them via WebDAV lock management tools. Since only exclusive locks are permitted, a user can only lock a resource if it is not already locked; however, multiple system locks can be
	 * put in place, because system locks imply that no user is permitted to change the resource.
	 * 
	 * @param id
	 * @param lockId
	 * @param subject -
	 *        the reason for this lock e.g. "being graded"
	 * @param system -
	 *        when true, it is not possible for a user to remove this lock
	 */
	public void lockObject(String id, String lockId, String subject, boolean system /* Date expiration , boolean exclusive, boolean inheritable */);

	/**
	 * Removes lock with given Id from object (resource or collection) specified by this local resource id. Note that other locks could exist, so it does not necessarily fully unlock the object.
	 * 
	 * @param id
	 * @param lockId
	 */
	public void removeLock(String id, String lockId);

	/**
	 * Convenience method to determine whether any locks exist for the Resource or Collection with the given local resource id
	 * 
	 * @param id
	 * @return true when there are one or more locks on the given id
	 */
	public boolean isLocked(String id);

	/**
	 * Returns true if this Collection or any of its contents has a lock. It is likely much more efficient than recursively iterating through all of the contained resources.
	 * 
	 * @param id
	 * @return
	 */
	public boolean containsLockedNode(String id);

	/**
	 * Convenience method that permanently removes any lock associated with qualifier
	 * 
	 * @param id
	 */
	public void removeAllLocks(String id);

	/**
	 * Does this resource support public view?
	 * 
	 * @param id
	 *        The resource id to check.
	 * @return true if this resource supports public view, false if not.
	 */
	public boolean isPubView(String id);

	/**
	 * Does this resource inherit public view by having it set in a containing folder (not counting it's own setting)?
	 * <p>Note that if you have a security advisor in place when you call this method, then this method will return true 
	 * regardless of the actual setting. (KNL-813).
	 *
	 * @param id
	 *        The resource id to check.
	 * @return true if this resource inherits public view, false if not.
	 */
	public boolean isInheritingPubView(String id);

	/**
	 * Set this resource or collection to the pubview setting.
	 * 
	 * @param id
	 *        The resource or collection id.
	 * @param pubview
	 *        The desired public view setting.
	 */
	public void setPubView(String id, boolean pubview);

	/**
	 * Grants or removes access to the content for a given role at a low level and should be used with caution.
	 * Recommend using org.sakaiproject.content.api.GroupAwareEdit#addRoleAccess and #removeRoleAccess instead.
	 *
	 * @param id
	 *        The resource or collection id.
	 * @param roleId
	 *        The id of the role to add or remove.
	 * @param grantAccess
	 *        The desired access setting - true gives access and false removes access.
	 */
	public void setRoleView(String id, String roleId, boolean grantAccess) throws AuthzPermissionException;

	/**
	 * Checks whether the given role is defined for the content.
	 *
	 * @param id
	 *        The resource or collection id.
	 * @param roleId
	 *        The id of the role to check for.
	 */
	public boolean isRoleView(String id, String roleId);

	/**
	 * Checks whether the role is defined for the container of the specified entity.
	 *
	 * @param id
	 *        The resource or collection id.
	 * @param roleId
	 *        The id of the role to check for.
	 */
	public boolean isInheritingRoleView(String id, String roleId);

	/**
	 * Gets a list of roles that are defined against this entity.
	 *
	 * @param id
	 *        The resource or collection id.
	 */
	public Set<String> getRoleViews(String id);

	/**
	 * Find all resources in specified sites that match the spcified type and mime type
	 * 
	 * @param type
	 *        this is the ResourceProperties.PROP_STRUCTOBJ_TYPE for stuctured objects or ResourceProperties.FILE_TYPE for file resources or null for all resources.
	 * @param primaryMimeType
	 *        The primary mime type (ie. the "text" of "text/xml") This may be null to include all resources
	 * @param subMimeType
	 *        The sub type (ie, the "xml" of "text/xml") This may be null to include all resources of the primary mime type if specified.
	 * @param contextIds	 
	 *			 select resources where CONTENT_RESOURCE.CONTEXT in [context,...]
	 * @return List of ContentResource objects that match the search criteria
	 */
	public List<ContentResource> findResources(String type, String primaryMimeType, String subMimeType,  Set<String> contextIds);
  
	/**
	 * Find all resources in sites the current user can access that match the spcified type and mime type
	 * 
	 * @param type
	 *        this is the ResourceProperties.PROP_STRUCTOBJ_TYPE for stuctured objects or ResourceProperties.FILE_TYPE for file resources or null for all resources.
	 * @param primaryMimeType
	 *        The primary mime type (ie. the "text" of "text/xml") This may be null to include all resources
	 * @param subMimeType
	 *        The sub type (ie, the "xml" of "text/xml") This may be null to include all resources of the primary mime type if specified.
	 * @return List of ContentResource objects that match the search criteria
	 */
	public List<ContentResource> findResources(String type, String primaryMimeType, String subMimeType);
  
	/**
	 * Return a map of Worksite collections roots that the user has access to.
	 * 
	 * @return Map of worksite resource root id (String) to worksite title (String) 
	 */
	public Map<String, String>  getCollectionMap();

	/**
	 * Eliminate from the collection any duplicates as well as any items that are contained within another item whose resource-id is in the collection.
	 * 
	 * @param resourceIds
	 *        A collection of strings (possibly empty) identifying items and/or collections.
	 */
	public void eliminateDuplicates(Collection<String> resourceIds);

	/**
	 * Create the current site's dropbox collection and one for each qualified user that the current user can make.
	 */
	public void createDropboxCollection();

	/**
	 * Create the site's dropbox collection and one for each qualified user that the current user can make.
	 * 
	 * @param siteId
	 *        the Site id.
	 */
	public void createDropboxCollection(String siteId);

	/**
	 * Access the default dropbox collection id for the current request.<br />
	 * If the current user is a dropbox maintainer for the current site, return the site's dropbox area.<br />
	 * Otherwis return the current user's collection within the site's dropbox.
	 * 
	 * @return The default dropbox collection id for the current request.
	 */
	public String getDropboxCollection();

	/**
	 * Create an individual dropbox collection for the current user if the site-level dropbox exists
	 * and the current user has EVENT_DROPBOX_OWN permission for the site.
	 * 
	 * @param siteId
	 *        the Site id.
	 */
	public void createIndividualDropbox(String siteId);

	/**
	 * Access the default dropbox collection id for the current request.<br />
	 * If the current user is a dropbox maintainer for the current site, return the site's dropbox area.<br />
	 * Otherwis return the current user's collection within the site's dropbox.
	 * 
	 * @param siteId
	 *        The site id.
	 * @return The default dropbox collection id for the site.
	 */
	public String getDropboxCollection(String siteId);

	/**
	 * Determine whether the default dropbox collection id for this user in this site is the site's entire dropbox collection or just the current user's collection within the site's dropbox.
	 * 
	 * @return True if user sees all dropboxes in the site, false otherwise.
	 */
	public boolean isDropboxMaintainer();

	/**
	 * Determine whether the default dropbox collection id for this user in some site is the site's entire dropbox collection or just the current user's collection within the site's dropbox.
	 * 
	 * @return True if user sees all dropboxes in the site, false otherwise.
	 */
	public boolean isDropboxMaintainer(String siteId);

	/**
	 * Determine whether the user has the dropbox.groups permission 
	 * 
	 * @return True if user has dropbox.groups permission, false otherwise.
	 */
	public boolean isDropboxGroups(String siteId);
	
	/**
	 * Access the default dropbox collection display name for the current request. If the current user has permission to modify the site's dropbox collection, this is returned. Otherwise, the current user's collection within the site's dropbox is
	 * returned.
	 * 
	 * @return The default dropbox collection display name for the current request.
	 */
	public String getDropboxDisplayName();

	/**
	 * Access the default dropbox collection display name for the site. If the current user has permission to modify the site's dropbox collection, this is returned. Otherwise, the current user's collection within the site's dropbox is returned.
	 * 
	 * @param siteId
	 *        the Site id.
	 * @return The default dropbox collection display name for the site.
	 */
	public String getDropboxDisplayName(String siteId);
	
	/**
	 * Check whether an id would identify an entity in a dropbox.  Does not determine existence of the entity, 
	 * just whether its id indicates it is a dropbox or contained within a dropbox.
	 * @return true if the entity is a dropbox or in a dropbox, false otherwise. 
	 */
	public boolean isInDropbox(String entityId);

	/**
	 * Check whether an id would identify as a site level dropbox. Does not determine existence of the entity,
	 * just whether its id indicates that it is a site level dropbox.
	 * @return true if the entity is a site level dropbox.
	 */
	public boolean isSiteLevelDropbox(String entityId);

	/**
	 * Check whether an id would identify as a user's dropbox. Does not determine existence of the entity nor of the user,
	 * just whether the entityId matches the format of a user dropbox (I.e. that it's a child of a site level dropbox)
	 * @return true if the entityId matches the format of a user's dropbox.
	 */
	public boolean isIndividualDropbox(String entityId);

	/**
	 * Check whether an id would identify as being inside a user's dropbox. Does not determine existence of the entity nor of the user,
	 * just whether its id indicates that it is inside a dropbox for a user (I.e. a descendent of an individual dropbox)
	 * @return true if the entityId's format suggests that it's inside a user's dropbox.
	 */
	public boolean isInsideIndividualDropbox(String entityId);
	
	/**
	 * Construct a content hosting comparator.
	 * 
	 * @param property
	 *        The property name used for the sort.
	 * @param ascending
	 *        true if the sort is to be ascending (false for descending).
	 */
	public Comparator newContentHostingComparator(String property, boolean ascending);
	
	/**
	 * Access a collection (Group) of groups to which this user has access and whose members have "content.read" permission in the collection. 
	 * In effect, this method returns a collection that identifies groups that are defined for the collection (locally or inherited) that 
	 * this user can access. If access to the collection is determined by group-membership, the return is limited to groups that have 
	 * access to the specified collection. If access is not defined by groups (i.e. it is "site" access), the return includes all groups
	 * defined in the site for which this user has read permission.
	 * 
	 * 
	 * @param collectionId
	 *        The id for the collection.
	 */
	public Collection getGroupsWithReadAccess(String collectionId);
	
	/**
	 * Access a collection (Group) of groups to which this user has access and whose members have "content.new" permission in the collection. 
	 * In effect, this method returns a collection that identifies groups that are defined for the collection (locally or inherited) in which 
	 * this user has permission to add content entities. If access to the collection is determined by group-membership, the return is limited 
	 * to groups that have "add" permission in the specified collection. If access is not defined by groups (i.e. it is "site" access), the return 
	 * includes all groups defined in the site for which this user has add permission in this collection.
	 * 
	 * @param collectionId
	 *        The id for the collection.
	 */
	public Collection getGroupsWithAddPermission(String collectionId);

	/**
	 * Access a collection (Group) of groups to which this user has access and whose members have "content.delete" permission in the collection. 
	 * In effect, this method returns a collection that identifies groups that are defined for the collection (locally or inherited) in which 
	 * this user has permission to remove content entities. If access to the collection is determined by group-membership, the return is limited 
	 * to groups that have "remove" permission in the specified collection. If access is not defined by groups (i.e. it is "site" access), the return 
	 * includes all groups defined in the site for which this user has remove permission in this collection.
	 * 
	 * @param collectionId
	 *        The id for the collection.
	 */
	public Collection getGroupsWithRemovePermission(String collectionId);

	/**
	 * Access the shortRefs configuration. Short refs allow resource URLs without full prefix (may have "~" instead of /user/, or be missing /group/).
	 * 
	 * @return true if shortRefs is enabled, false if not.
	 */
	public boolean isShortRefs();
	
	/**
	 * Access flag indicating whether entities can be hidden (scheduled or otherwise).
	 * @return true if the availability features are enabled, false otherwise.
	 */
	public boolean isAvailabilityEnabled();
	
	/**
	 * Determine whether an entity is available to this user at this time, taking into account whether the item is hidden and the user's 
	 * status with respect to viewing hidden entities in this context.
	 * @param entityId
	 * @return true if the item is not hidden or it's hidden but the user has permissions to view hidden items in this context (site? folder? group?), 
	 * and false otherwise. 
	 */
	public boolean isAvailable(String entityId);
	
	/**
	 * Access flag indicating whether sorting by "priority" is enabled.
	 * @return true if the custom sort by priority is enabled, false otherwise.
	 */ 
	public boolean isSortByPriorityEnabled();
	
	/**
	 * Determine whether the entityId parameter identifies a collection (as opposed to a resource).  
	 * This method does not necessarily verify that a ContentEntity with this id exists.  
	 * It merely determines whether the id could identify a collection.
	 * @param entityId The entity ID which might be a collection.
	 * @return true if the entityId could identify a collection, false otherwise.
	 */
	public boolean isCollection(String entityId);

	/**
	 * Attempt to create a new resource in a particular collection.  Ideally, this method will create
	 * a new resource in the collection identified by the first parameter, collectionId, with a name
	 * formed by concatenating the basename and the extension.  If the extension is not null or empty 
	 * and does not start with a period ('.'), a period will be prepended to the extension. If the name 
	 * formed by concatenating the basename and the extension, some number of attempts may be made to 
	 * find a unique name for the resource in the collection by adding a dash ('-') and a number to the
	 * basename.  The fourth parameter, "maximum_tries", will determine the number of attempts to find 
	 * a unique name for the resource in the collection. The numbers appended to the basename will start
	 * with '1' and increase by 1 until a unique name is found or the maximum value is reached.   
	 * 
	 * @param collectionId
	 * @param basename
	 * @param extension
	 * @param maximum_tries
	 * @exception PermissionException
	 *            if the user does not have permission to add a resource to the containing collection.
	 * @exception IdUnusedException
	 *            if the collectionId does not identify an existing collection. 
	 * @exception IdUniquenessException
	 *            if a unique resource id cannot be found before the limit on the number of attempts is reached.
	 * @exception IdLengthException
	 *            if the resource id exceeds the maximum number of characters for a valid resource id.
	 * @exception IdInvalidException
	 *            if the resource id is invalid.
	 * @exception InconsistentException
	 *            if the containing collection does not exist.
	 * @exception OverQuotaException
	 *            if this would result in being over quota.
	 * @exception ServerOverloadException
	 *            if the server is configured to write the resource body to the filesystem and the save fails.
	 * @return
	 */
	public ContentResourceEdit addResource(String collectionId, String basename, String extension, int maximum_tries)
		throws PermissionException, IdUniquenessException, IdLengthException, IdInvalidException, 
			IdUnusedException, OverQuotaException, ServerOverloadException;

	/**
	 * @param collectionId
	 * @param name
	 * @return
	 * @exception PermissionException
	 *            if the user does not have permission to add a resource to the containing collection.
	 * @exception TypeException 
	 *            if the collectionId is not in the form to identify a collection. 
	 * @exception IdUnusedException
	 *            if the collectionId does not identify an existing collection. 
	 * @exception IdUnusedException
	 *            if the collection id for the proposed name already exists in this collection.
	 * @exception IdLengthException
	 *            if the new collection id exceeds the maximum number of characters for a valid collection id.
	 * @exception IdInvalidException
	 *            if the resource id is invalid.
	 */
	public ContentCollectionEdit addCollection(String collectionId, String name)
		throws PermissionException, IdUnusedException, IdUsedException, 
				IdLengthException, IdInvalidException, TypeException;

	/**
	 * This method with the limit parameter should be used if you want to create a unique collection id.
	 * Because the Resources tool allows renaming folders, the end-user can become confused when folder
	 * creation is denied because the resourceId was already taken.
	 * 
	 * @param collectionId
	 * @param name
	 * @param limit
	 *            number of attempts to find a unique resourceId for the collection via incrementing
	 * @return
	 * @exception PermissionException
	 *            if the user does not have permission to add a resource to the containing collection.
	 * @exception TypeException
	 *            if the collectionId is not in the form to identify a collection.
	 * @exception IdUnusedException
	 *            if the collectionId does not identify an existing collection.
	 * @exception IdUnusedException
	 *            if the collection id for the proposed name already exists in this collection.
	 * @exception IdLengthException
	 *            if the new collection id exceeds the maximum number of characters for a valid collection id.
	 * @exception IdInvalidException
	 *            if the resource id is invalid.
	 * @exception IdUniquenessException
	 *            if a unique id for the collection cannot be found despite using an incrementor
	 */
	public ContentCollectionEdit addCollection(String collectionId, String name, int limit)
		throws PermissionException, IdUnusedException, IdUsedException,
				IdLengthException, IdInvalidException, TypeException, IdUniquenessException;

   /**
    * gets the quota for a site collection or for a user's Home collection
    *
    * @param collection the collection on which to test for a quota.  this can be the collection for a site
    * or a user's workspace collection
    * @return the quota in kb
    */
    public long getQuota(org.sakaiproject.content.api.ContentCollection collection);
    
    /**
     * Access flag indicating whether ContentHostingHandlers are enabled in this content hosting service.
     * @return true if ContentHostingHandlers are enabled, false otherwise.
     */
    public boolean isContentHostingHandlersEnabled();

    /**
     * Access the name of the individual dropbox that contains a particular entity, or null if the entity is not inside an individual dropbox.
     * @param entityId The id for an entity
     * @return
     */
	public String getIndividualDropboxId(String entityId);
	
	/**
	 * Retrieve a collection of ContentResource objects pf a particular resource-type.  The collection will 
	 * contain no more than the number of items specified as the pageSize, where pageSize is a non-negative 
	 * number less than or equal to 1028. The resources will be selected in ascending order by resource-id.
	 * If the resources of the specified resource-type in the ContentHostingService in ascending order by 
	 * resource-id are indexed from 0 to M and this method is called with parameters of N for pageSize and 
	 * I for page, the resources returned will be those with indexes (I*N) through ((I+1)*N - 1).  For example,
	 * if pageSize is 1028 and page is 0, the resources would be those with indexes of 0 to 1027.  
	 * This method finds the resources the current user has access to from a "page" of all resources
	 * of the specified type. If that page contains no resources the current user has access to, the 
	 * method returns an empty collection.  If the page does not exist (i.e. there are fewer than 
	 * ((page+1)*page_size) resources of the specified type), the method returns null.    
    *
	 * @param resourceType select resources where CONTENT_RESOURCE.RESOURCE_TYPE_ID equals resourceType
	 * @param pageSize (page) size of results
	 * @param page (page) increment of results
	 * @return collection of ContentResource
	 * @see org.sakaiproject.content.api.ContentHostingService#MAXIMUM_PAGE_SIZE
	 */
	public Collection<ContentResource> getResourcesOfType(String resourceType, int pageSize, int page);

	/**
	 * Retrieve a collection of ContentResource objects of a particular resource-type in a set of contexts
	 *
	 * @param resourceType select resources where CONTENT_RESOURCE.RESOURCE_TYPE_ID equals resourceType
	 * @param contextIds	 select resources where CONTENT_RESOURCE.CONTEXT in [context,...]
	 * @return collection of ContentResource
	 */
	public Collection<ContentResource> getContextResourcesOfType(String resourceType, Set<String> contextIds);


	/**
	 * Restore the resource with this resource id.
	 * 
	 * @param id
	 *        The id of the resource.
	 * @exception PermissionException
	 *            if the user does not have permissions to read the resource or read through any containing collection.
	 * @exception IdUnusedException
	 *            if the resource id is not found.
	 * @exception TypeException
	 *            if the resource is a collection.
	 * @exception InUseException
	 *            if the resource is locked by someone else.
	 * @return the ContentResource object found.
	 */
	public void restoreResource(String id) throws PermissionException, IdUsedException, IdUnusedException,
	IdInvalidException, InconsistentException, OverQuotaException, ServerOverloadException, TypeException, InUseException;

	/**
	 * Permanently remove the resource with this resource id.
	 * 
	 * @param id
	 *        The id of the resource.
	 * @throws PermissionException 
	 */
	public void removeDeletedResource(String resourceId) throws PermissionException, IdUnusedException, TypeException, InUseException; 

	/**
	 * Return a direct link to retrieve the asset instead of streaming the asset inside the JVM. See SAK-30325
	 *
	 * @param resourceId The file resource that may have a direct link available
	 *
	 * @return URI that will return the asset directly
	 */
	public URI getDirectLinkToAsset(ContentResource resource) throws Exception;

	/**
	 * Expand the supplied resource under its parent collection. See KNL-273
	 *
	 * @param resourceId The zip file resource that we want to expand
	 */
	public void expandZippedResource(String resourceId) throws Exception;

	/**
	 * Expand macros in a URL
	 *
	 * @param url - string, a URL to be expanded
	 *
	 * @return URL with macro expansion
	 */
	public String expandMacros(String url);

	/**
	 * Return a list of the mimetypes handled by the built in Apache based converter.
	 *
	 * @return The mimetypes handled by the built in Apache based converter.
	 */
	public List<String> getHtmlForRefMimetypes();

	/**
	 * Returns a map with the converted document html and the conversions status
	 */
	public Map<String,String> getHtmlForRef(String ref);

	/**
	 * Get the name of the "instructor" upload folder name for direct-upload.
	 * This is the folder for users that have addCollection permission in the
	 * site.
	 *
	 * @return String - The name of the folder.
	 */
	public String getInstructorUploadFolderName();

	/**
	 * Get the name of the "student" upload folder name for direct-upload.
	 * This is the folder for users that do not have addCollection permission
	 * in the site.
	 *
	 * @return String - The name of the folder.
	 */
	public String getStudentUploadFolderName();
}
